<script setup>
import { ref, h, computed } from "vue";
import {
  AreaChartOutlined,
  VerticalAlignBottomOutlined,
} from "@ant-design/icons-vue";
import { message as antMessage } from "ant-design-vue";
import myRow from "@/components/common/myRow.vue";
import myLabel from "@/components/common/myLabel.vue";
import { useDraw } from "@/hooks/useDraw.js";
import { getLsaData } from "@/apis/index.js";
import { useGenerateData } from "@/hooks/useGenerateData";
import { options as defaultOptions } from "@/stores/options";
import editNodeForm from "@/components/editNodeForm.vue";
import editEdgeForm from "@/components/editEdgeForm.vue";
// =========上传文件获取数据逻辑=========
const isUploading = ref(false);
const uploadRef = ref(null);
const behaviorList = ref([]);
const lsaData = ref([]);
const renderList = ref([]);
const nodes = ref([]);
const edges = ref([]);

const { getColumn } = useGenerateData();

const handleUpload = () => {
  if (uploadRef.value.files.length === 0) {
    antMessage.error("请先上传文件");
    return;
  }
  // 发送请求
  let result;
  getLsaData(uploadRef.value.files)
    .then((res) => {
      let { message, success } = res.data;
      result = res.data.data;
      if (success) {
        antMessage.success(message);
        behaviorList.value = result.behaviorList;
        lsaData.value = result.lsaData;
        renderList.value = result.renderList;
        nodes.value = result.nodes;
        edges.value = result.edges;
      } else {
        antMessage.error(message);
      }
    })
    .catch((err) => {
      antMessage.error("未知错误!");
    });
};

const behviorColumn = computed(() => {
  return getColumn(behaviorList.value);
});

// =========绘制逻辑=============
const { handleDrawLsa, getInfoOfLine } = useDraw();

// 准备数据
const visContainer = ref(null);
const options = ref(defaultOptions);
const network = ref(null);
const open = ref(false);

// 点击绘制
const handleClickToDraw = () => {
  // container, options, nodes, edges
  network.value = handleDrawLsa(
    visContainer.value,
    options.value,
    nodes.value,
    edges.value
  );
  // 为网络添加点击事件
  network.value.on("click", function () {
    if (network.value.getSelectedNodes().length !== 0) {
      open.value = true;
      //  DONE: 编辑节点功能
      isEditingNode.value = true;
      let nodeNumber = network.value.getSelectedNodes()[0];
      let nodeText = behaviorList.value[Number(nodeNumber)];
      editingNode.value = nodeText;
    } else if (network.value.getSelectedEdges().length !== 0) {
      open.value = true;
      isEditingNode.value = false;
      editingEdge.value = getInfoOfLine(network.value);
    }
  });
};

// 点击下载
const handleDownload = () => {
  const canvas = visContainer.value.querySelector("canvas");
  canvas.style.background = "#fff";
  if (!canvas) {
    antMessage.warning("请先绘制图片!");
    return;
  }
  const el = document.createElement("a");
  el.href = canvas.toDataURL();
  el.download = "lsa.png";

  const event = new MouseEvent("click");
  el.dispatchEvent(event);
  el.remove();
  antMessage.success("下载成功!");
};

// 编辑的是节点还是边
const isEditingNode = ref(false);

// ======== 编辑节点功能 =========
const editingNode = ref("");

const handleChangeNode = (nodeOptions) => {
  for (let i = 0; i < nodes.value.length; i++) {
    if (nodes.value[i].label === editingNode.value) {
      nodes.value[i] = { ...nodes.value[i], ...nodeOptions };
      break;
    }
  }
  // 重新绘制LSA图片
  handleClickToDraw();
};

// ========= 编辑边的功能 =========
const editingEdge = ref({ from: 0, to: 1 });

const handleChangeEdge = (edgeOptions) => {
  for (let i = 0; i < edges.value.length; i++) {
    if (
      edges.value[i].from === editingEdge.value.from &&
      edges.value[i].to === editingEdge.value.to
    ) {
      edges.value[i] = { ...edges.value[i], ...edgeOptions };
    }
  }
  // 重新绘制LSA图片
  handleClickToDraw();
};
</script>

<template>
  <div class="container">
    <main>
      <!-- 单独编辑每一个节点或者边线 -->
      <!-- DONE: 搭建编辑节点的结构 -->
      <a-drawer v-model:open="open">
        <edit-node-form
          v-if="isEditingNode"
          :node="editingNode"
          @saveNodeOptions="handleChangeNode"
        ></edit-node-form>
        <!-- DONE: 搭建编辑边的结构 -->
        <edit-edge-form
          v-else
          :edge="editingEdge"
          :behaviorList="behaviorList"
          @saveEdgeOptions="handleChangeEdge"
        >
        </edit-edge-form>
      </a-drawer>
      <h1>
        自动绘制LSA图
        <el-link href="https://gitee.com/tomFfff/lsa.git" target="_blank"
          >项目链接</el-link
        >
      </h1>
      <section class="echarts" ref="visContainer"></section>
      <div class="button">
        <a-button
          type="primary"
          @click="handleClickToDraw"
          :icon="h(AreaChartOutlined)"
          >绘制</a-button
        >
        <a-button
          type="primary"
          @click="handleDownload"
          :icon="h(VerticalAlignBottomOutlined)"
          >保存</a-button
        >
      </div>
      <section class="control">
        <div class="graph-form">
          <a-card title="解析数据" hoverable style="flex: 1">
            <a-form>
              <a-form-item>
                <div class="small-title">上传Excel文件</div>
                <my-row>
                  <input
                    type="file"
                    name="file"
                    ref="uploadRef"
                    class="fileUpload"
                  />
                  <a-button :disabled="isUploading" @click="handleUpload"
                    >上传</a-button
                  >
                </my-row>
              </a-form-item>
              <a-form-item>
                <div class="small-title">行为序列</div>
                <my-row>
                  <a-tag v-for="(item, index) in behaviorList" :key="index">{{
                    item
                  }}</a-tag>
                </my-row>
              </a-form-item>
              <a-form-item>
                <div class="small-title">结果展示</div>
                <div class="render-table" v-if="renderList.length > 0">
                  <a-table
                    :dataSource="renderList"
                    :columns="behviorColumn"
                    size="small"
                    :pagination="false"
                  ></a-table>
                </div>
              </a-form-item>
            </a-form>
          </a-card>
          <a-card title="控制显示" hoverable style="flex: 1">
            <my-row title="节点配置">
              <my-label label="边框颜色">
                <el-color-picker
                  v-model="options.nodes.color.border"
                ></el-color-picker>
              </my-label>
              <my-label label="背景颜色">
                <el-color-picker
                  v-model="options.nodes.color.background"
                ></el-color-picker>
              </my-label>
              <my-label label="节点大小">
                <section style="width: 300px">
                  <a-slider
                    v-model:value="options.nodes.widthConstraint"
                  ></a-slider>
                </section>
              </my-label>
              <my-label label="字体大小">
                <section style="width: 300px">
                  <a-slider v-model:value="options.nodes.font.size"></a-slider>
                </section>
              </my-label>
              <my-label label="字体颜色">
                <el-color-picker
                  v-model="options.nodes.font.color"
                ></el-color-picker>
              </my-label>
            </my-row>
            <my-row title="边配置">
              <my-label label="边颜色">
                <el-color-picker
                  v-model="options.edges.color.color"
                ></el-color-picker>
              </my-label>
              <my-label label="字体大小">
                <section style="width: 300px">
                  <a-slider v-model:value="options.edges.font.size"></a-slider>
                </section>
              </my-label>
              <my-label label="字体颜色">
                <el-color-picker
                  v-model="options.edges.font.color"
                ></el-color-picker>
              </my-label>
              <my-label label="粗细">
                <section style="width: 300px">
                  <a-slider
                    v-model:value="options.edges.width"
                    :min="1"
                    :max="10"
                  ></a-slider>
                </section>
              </my-label>
              <my-label label="长度">
                <section style="width: 300px">
                  <a-slider
                    v-model:value="options.edges.length"
                    :min="100"
                    :max="500"
                  >
                  </a-slider>
                </section>
              </my-label>
            </my-row>
          </a-card>
        </div>
      </section>
    </main>
  </div>
</template>

<style lang="scss" scoped>
.container {
  width: 100vw;
  height: 100vh;
  padding: 10px;
  display: flex;
  justify-content: center;
  overflow-x: hidden;
  h1 {
    text-align: center;
    font-size: 24px;
    margin-bottom: 10px;
    color: var(--primary-color);
  }
  .echarts {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 80%;
    border: 2px solid var(--primary-color);
    margin-bottom: 10px;
    background-color: #fff;
  }
}
.button {
  display: flex;
  justify-content: center;
  gap: 10px;
}
.graph-form {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  margin-top: 20px;
}
.small-title {
  font-size: 20px;
  color: var(--primary-color);
  margin-bottom: 5px;
  font-weight: 700;
}
</style>
